//File   : wav_parser.h 
//Author : Loon <sepnic@gmail.com> 
 
#ifndef __WAV_PARSER_H 
#define __WAV_PARSER_H 
 
typedef unsigned char  uint8_t; 
typedef unsigned short uint16_t; 
typedef unsigned int   uint32_t; 
 
#if __BYTE_ORDER == __LITTLE_ENDIAN 
#define COMPOSE_ID(a,b,c,d)     ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) 
#define LE_SHORT(v)             (v) 
#define LE_INT(v)               (v) 
#define BE_SHORT(v)             bswap_16(v) 
#define BE_INT(v)               bswap_32(v) 
#elif __BYTE_ORDER == __BIG_ENDIAN 
#define COMPOSE_ID(a,b,c,d)     ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24)) 
#define LE_SHORT(v)             bswap_16(v) 
#define LE_INT(v)               bswap_32(v) 
#define BE_SHORT(v)             (v) 
#define BE_INT(v)               (v) 
#else 
#error "Wrong endian" 
#endif 
 
#define WAV_RIFF        COMPOSE_ID('R','I','F','F') 
#define WAV_WAVE        COMPOSE_ID('W','A','V','E') 
#define WAV_FMT         COMPOSE_ID('f','m','t',' ') 
#define WAV_DATA        COMPOSE_ID('d','a','t','a') 
 
/* WAVE fmt block constants from Microsoft mmreg.h header */ 
#define WAV_FMT_PCM             0x0001 
#define WAV_FMT_IEEE_FLOAT      0x0003 
#define WAV_FMT_DOLBY_AC3_SPDIF 0x0092 
#define WAV_FMT_EXTENSIBLE      0xfffe 
 
/* Used with WAV_FMT_EXTENSIBLE format */ 
#define WAV_GUID_TAG "/x00/x00/x00/x00/x10/x00/x80/x00/x00/xAA/x00/x38/x9B/x71" 
 
/* it's in chunks like .voc and AMIGA iff, but my source say there 
   are in only in this combination, so I combined them in one header; 
   it works on all WAVE-file I have 
 */ 
typedef struct WAVHeader { 
    uint32_t magic;             /* 'RIFF' */ 
    uint32_t length;            /* filelen */ 
    uint32_t type;              /* 'WAVE' */ 
} WAVHeader_t; 
 
typedef struct WAVFmt { 
    uint32_t magic;             /* 'FMT '*/ 
    uint32_t fmt_size;          /* 16 or 18 */ 
    uint16_t format;            /* see WAV_FMT_* */ 
    uint16_t channels; 
    uint32_t sample_rate;       /* frequence of sample */ 
    uint32_t bytes_p_second; 
    uint16_t blocks_align;      /* samplesize; 1 or 2 bytes */ 
    uint16_t sample_length;     /* 8, 12 or 16 bit */ 
} WAVFmt_t; 
 
typedef struct WAVFmtExtensible { 
    WAVFmt_t format; 
    uint16_t ext_size; 
    uint16_t bit_p_spl; 
    uint32_t channel_mask; 
    uint16_t guid_format;       /* WAV_FMT_* */ 
    uint8_t guid_tag[14];       /* WAV_GUID_TAG */ 
} WAVFmtExtensible_t; 
 
typedef struct WAVChunkHeader { 
    uint32_t type;              /* 'data' */ 
    uint32_t length;            /* samplecount */ 
} WAVChunkHeader_t; 
 
typedef struct WAVContainer { 
    WAVHeader_t header; 
    WAVFmt_t format; 
    WAVChunkHeader_t chunk; 
} WAVContainer_t; 
 
int WAV_ReadHeader(int fd, WAVContainer_t *container); 
 
int WAV_WriteHeader(int fd, WAVContainer_t *container); 
 
#endif /* #ifndef __WAV_PARSER_H */ 